package com.uit.gis.ui;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ScrollPaneConstants;
import javax.swing.SpringLayout;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;

import processing.core.PApplet;

import com.uit.gis.controller.MainController;
import com.uit.gis.pojo.Shape;
import com.uit.gis.pojo.ShapeFactory;
import com.uit.gis.util.DatabaseDefine.TABLE_STATUS;
import com.uit.gis.util.Language;
import com.uit.gis.util.ShapeName;
import com.uit.gis.util.Util.MessageBox;
import com.uit.gis.util.Util.MessageBoxIcon;

public class PanelDrawing extends JPanel implements ActionListener {

	/**
	 * 
	 */
	private static final long serialVersionUID = -3607918047215805449L;
	static final String CM_SAVE = "CM_SAVE";

	static final String CM_LINE = "CM_LINE";
	static final String CM_TRIANGLE = "CM_TRIANGLE";
	static final String CM_POINTS = "CM_POINTS";
	static final String CM_ELLIPSE = "CM_ELLIPSE";
	static final String CM_BOX = "CM_BOX";
	static final String CM_CUSTOM_SHAPE = "CM_CUSTOM_SHAPE";
	static final String CM_QUAD = "CM_QUAD";
	static final String CM_RECTANGLE = "CM_RECTANGLE";

	static final String CM_CIRCLE = "CM_CIRCLE";
	static final String CM_ARC = "CM_ARC";

	/**
	 * Create the panel.
	 */
	MainController controller;
	JButton btnLine;
	JPanel panel;
	JButton btnSaveShape;
	ShapeFactory shapeFactory;
	JLabel lbStatus;
	JLabel lbdatabaseStatus;
	Shape currentShape;
	JPanel panelDatabase;
	JTable table;

	public PanelDrawing(MainController controller) {
		setToolTipText("");
		this.controller = controller;
		shapeFactory = new ShapeFactory();

		SpringLayout springLayout = new SpringLayout();
		setLayout(springLayout);

		panel = new JPanel(new GridLayout(1, 1));
		panel.setOpaque(true);
		panel.setBackground(Color.WHITE);
		springLayout.putConstraint(SpringLayout.SOUTH, panel, 299,
				SpringLayout.NORTH, this);
		springLayout.putConstraint(SpringLayout.EAST, panel, 600,
				SpringLayout.WEST, this);
		panel.setBorder(new TitledBorder(UIManager
				.getBorder("TitledBorder.border"), "Drawing area",
				TitledBorder.LEADING, TitledBorder.TOP, null,
				new Color(0, 0, 0)));
		springLayout.putConstraint(SpringLayout.NORTH, panel, 33,
				SpringLayout.NORTH, this);
		springLayout.putConstraint(SpringLayout.WEST, panel, 37,
				SpringLayout.WEST, this);

		add(panel);
		JLabel lblTipsClickRight = new JLabel(
				"Tips: Click right mouse to stop draw and export coordinates to file.");
		springLayout.putConstraint(SpringLayout.NORTH, lblTipsClickRight, 6,
				SpringLayout.SOUTH, panel);
		springLayout.putConstraint(SpringLayout.WEST, lblTipsClickRight, 0,
				SpringLayout.WEST, panel);
		springLayout.putConstraint(SpringLayout.SOUTH, lblTipsClickRight, -186,
				SpringLayout.SOUTH, this);
		springLayout.putConstraint(SpringLayout.EAST, lblTipsClickRight, 393,
				SpringLayout.WEST, panel);
		lblTipsClickRight.setForeground(Color.RED);
		add(lblTipsClickRight);

		panelDatabase = new JPanel(new GridLayout(1, 0));
		springLayout.putConstraint(SpringLayout.NORTH, panelDatabase, 6,
				SpringLayout.SOUTH, lblTipsClickRight);
		springLayout.putConstraint(SpringLayout.WEST, panelDatabase, 0,
				SpringLayout.WEST, panel);
		springLayout.putConstraint(SpringLayout.SOUTH, panelDatabase, -10,
				SpringLayout.SOUTH, this);
		springLayout.putConstraint(SpringLayout.EAST, panelDatabase, 0,
				SpringLayout.EAST, panel);
		panelDatabase.setBorder(new TitledBorder(null,
				"Current shapes in database", TitledBorder.LEADING,
				TitledBorder.TOP, null, null));
		add(panelDatabase);

		GridBagLayout gbl_panelShapes = new GridBagLayout();
		gbl_panelShapes.columnWeights = new double[] { 0.0, 0.0, 0.0, 0.0 };
		JPanel panelShapes = new JPanel(gbl_panelShapes);
		springLayout.putConstraint(SpringLayout.NORTH, panelShapes, 33, SpringLayout.NORTH, this);
		springLayout.putConstraint(SpringLayout.WEST, panelShapes, 25,
				SpringLayout.EAST, panel);
		springLayout.putConstraint(SpringLayout.SOUTH, panelShapes, 0, SpringLayout.SOUTH, panel);
		panelShapes.setBorder(new TitledBorder(null, "Shapes",
				TitledBorder.LEADING, TitledBorder.TOP, null, null));
		add(panelShapes);

		JButton btnEllipse =     new JButton("Ellipse"); 
		GridBagConstraints gbc_btnEllipse = new GridBagConstraints();
		gbc_btnEllipse.fill = GridBagConstraints.BOTH;
		gbc_btnEllipse.gridwidth = 3;
		gbc_btnEllipse.insets = new Insets(0, 0, 5, 5);
		gbc_btnEllipse.gridx = 0;
		gbc_btnEllipse.gridy = 0;
		gbc_btnEllipse.weightx = 30;
		gbc_btnEllipse.weighty = 20;
		btnEllipse.setVisible(false);
		panelShapes.add(btnEllipse, gbc_btnEllipse);

		JButton btnCustomShape = new JButton("Custom Shape");
		GridBagConstraints gbc_btnCustomShape = new GridBagConstraints();
		gbc_btnCustomShape.insets = new Insets(0, 0, 5, 0);
		gbc_btnCustomShape.gridx = 3;
		gbc_btnCustomShape.gridy = 0;
		gbc_btnCustomShape.gridwidth = 3;
		gbc_btnCustomShape.weightx = 20;
		gbc_btnCustomShape.weighty = 20;
		gbc_btnCustomShape.fill = GridBagConstraints.BOTH;
		panelShapes.add(btnCustomShape, gbc_btnCustomShape);
		springLayout.putConstraint(SpringLayout.WEST, btnCustomShape, 715,
				SpringLayout.WEST, this);
		springLayout.putConstraint(SpringLayout.EAST, btnCustomShape, -40,
				SpringLayout.EAST, this);

		JButton btnRectangle = new JButton("  Rectangle  ");
		GridBagConstraints gbc_btnRectangle = new GridBagConstraints();
		gbc_btnRectangle.fill = GridBagConstraints.BOTH;
		gbc_btnRectangle.gridwidth = 3;
		gbc_btnRectangle.insets = new Insets(0, 0, 5, 5);
		gbc_btnRectangle.gridx = 0;
		gbc_btnRectangle.gridy = 1;
		gbc_btnRectangle.weightx = 20;
		gbc_btnRectangle.weighty = 20;
		panelShapes.add(btnRectangle, gbc_btnRectangle);
		springLayout.putConstraint(SpringLayout.NORTH, btnRectangle, 44,
				SpringLayout.NORTH, this);
		springLayout.putConstraint(SpringLayout.WEST, btnRectangle, 197,
				SpringLayout.EAST, panel);
		springLayout.putConstraint(SpringLayout.EAST, btnRectangle, -106,
				SpringLayout.EAST, this);

		JButton btnTriangle = new JButton("Triangle");
		GridBagConstraints gbc_btnTriangle = new GridBagConstraints();
		gbc_btnTriangle.fill = GridBagConstraints.BOTH;
		gbc_btnTriangle.insets = new Insets(0, 0, 5, 0);
		gbc_btnTriangle.gridx = 3;
		gbc_btnTriangle.gridy = 1;
		gbc_btnTriangle.gridwidth = 3;
		gbc_btnTriangle.weightx = gbc_btnTriangle.weighty = 20;
		panelShapes.add(btnTriangle, gbc_btnTriangle);
		springLayout.putConstraint(SpringLayout.NORTH, btnTriangle, 159,
				SpringLayout.NORTH, this);
		springLayout.putConstraint(SpringLayout.WEST, btnTriangle, 64,
				SpringLayout.EAST, panel);
		springLayout.putConstraint(SpringLayout.SOUTH, btnTriangle, -386,
				SpringLayout.SOUTH, this);

		JButton btnPoints = new JButton("Points");
		GridBagConstraints gbc_btnPoints = new GridBagConstraints();
		gbc_btnPoints.fill = GridBagConstraints.BOTH;
	
		gbc_btnPoints.insets = new Insets(0, 0, 5, 5);
		gbc_btnPoints.gridx = 0;
		gbc_btnPoints.gridy = 2;
		gbc_btnPoints.gridwidth = 3;
		gbc_btnPoints.weightx = gbc_btnPoints.weighty = 20;
		panelShapes.add(btnPoints, gbc_btnPoints);
		springLayout.putConstraint(SpringLayout.NORTH, btnPoints, 159,
				SpringLayout.NORTH, this);
		springLayout.putConstraint(SpringLayout.WEST, btnPoints, -149,
				SpringLayout.EAST, this);
		springLayout.putConstraint(SpringLayout.EAST, btnPoints, -40,
				SpringLayout.EAST, this);
		springLayout.putConstraint(SpringLayout.EAST, btnTriangle, -91,
				SpringLayout.WEST, btnPoints);

		JButton btnQuad = new JButton("Quad");
		GridBagConstraints gbc_btnQuad = new GridBagConstraints();
		gbc_btnQuad.fill = GridBagConstraints.BOTH;
		gbc_btnQuad.insets = new Insets(0, 0, 5, 0);
		gbc_btnQuad.gridx = 3;
		gbc_btnQuad.gridy = 2;
		gbc_btnQuad.gridwidth = 3;
		gbc_btnQuad.weightx = gbc_btnQuad.weighty= 20;
		panelShapes.add(btnQuad, gbc_btnQuad);
		springLayout.putConstraint(SpringLayout.WEST, btnQuad, 118,
				SpringLayout.EAST, lblTipsClickRight);
		springLayout.putConstraint(SpringLayout.SOUTH, btnQuad, -232,
				SpringLayout.SOUTH, this);

		JButton btnBox = new JButton("Box");
		GridBagConstraints gbc_btnBox = new GridBagConstraints();
		gbc_btnBox.gridwidth = 3;
		gbc_btnBox.fill = GridBagConstraints.BOTH;
		gbc_btnBox.insets = new Insets(0, 0, 5, 5);
		gbc_btnBox.gridx = 0;
		gbc_btnBox.gridy = 3;
		gbc_btnBox.weightx = gbc_btnBox.weighty = 20;
		panelShapes.add(btnBox, gbc_btnBox);
		springLayout.putConstraint(SpringLayout.WEST, btnBox, 715,
				SpringLayout.WEST, this);
		springLayout.putConstraint(SpringLayout.EAST, btnBox, -40,
				SpringLayout.EAST, this);
		springLayout.putConstraint(SpringLayout.NORTH, btnBox, 195,
				SpringLayout.NORTH, this);
		springLayout.putConstraint(SpringLayout.SOUTH, btnBox, -307,
				SpringLayout.SOUTH, this);

		btnSaveShape = new JButton("Save to database");
		springLayout.putConstraint(SpringLayout.EAST, panelShapes, 0,
				SpringLayout.EAST, btnSaveShape);
		springLayout.putConstraint(SpringLayout.NORTH, btnSaveShape, -70,
				SpringLayout.SOUTH, this);
		springLayout.putConstraint(SpringLayout.SOUTH, btnSaveShape, -34,
				SpringLayout.SOUTH, this);
		springLayout.putConstraint(SpringLayout.EAST, btnSaveShape, -52,
				SpringLayout.EAST, this);
		this.add(btnSaveShape);

		JButton btnLine = new JButton("Line");
		GridBagConstraints gbc_btnLine = new GridBagConstraints();
		gbc_btnLine.insets = new Insets(0, 0, 5, 0);
		gbc_btnLine.fill = GridBagConstraints.BOTH;
		gbc_btnLine.gridx = 3;
		gbc_btnLine.gridy = 3;
		gbc_btnLine.gridwidth = 3;
		gbc_btnLine.weightx = gbc_btnLine.weighty = 20;
		panelShapes.add(btnLine, gbc_btnLine);

		lbStatus = new JLabel("Status");
		springLayout.putConstraint(SpringLayout.NORTH, lbStatus, 27, SpringLayout.SOUTH, panelShapes);
		springLayout.putConstraint(SpringLayout.WEST, lbStatus, 0, SpringLayout.WEST, panelShapes);
		springLayout.putConstraint(SpringLayout.EAST, lbStatus, -10, SpringLayout.EAST, this);

		JButton btnArc = new JButton("Arc");
		GridBagConstraints gbc_btnArc = new GridBagConstraints();
		gbc_btnArc.fill = GridBagConstraints.BOTH;
		gbc_btnArc.weightx = gbc_btnArc.weighty = 20; 
		gbc_btnArc.insets = new Insets(0, 0, 0, 5);
		gbc_btnArc.gridx = 0;
		gbc_btnArc.gridy = 4;
		gbc_btnArc.gridwidth = 3;
		panelShapes.add(btnArc, gbc_btnArc);

		JButton btnCircle = new JButton("Circle");
		GridBagConstraints gbc_btnCircle = new GridBagConstraints();
		gbc_btnCircle.fill = GridBagConstraints.BOTH;
		gbc_btnCircle.gridx = 3;
		gbc_btnCircle.gridy = 4;
		gbc_btnCircle.gridwidth = 3;
		gbc_btnCircle.weightx = gbc_btnCircle.weighty = 20; 
		panelShapes.add(btnCircle, gbc_btnCircle);
		lbStatus.setForeground(Color.BLUE);
		add(lbStatus);

		lbdatabaseStatus = new JLabel("Disconnected");
		springLayout.putConstraint(SpringLayout.WEST, lbdatabaseStatus, 0, SpringLayout.WEST, panelShapes);
		springLayout.putConstraint(SpringLayout.SOUTH, lbdatabaseStatus, -138, SpringLayout.SOUTH, this);
		add(lbdatabaseStatus);
		// Button commands - begin
		btnSaveShape.addActionListener(this);
		btnSaveShape.setActionCommand(CM_SAVE);

		btnEllipse.addActionListener(this);
		btnEllipse.setActionCommand(CM_ELLIPSE);

		btnLine.addActionListener(this);
		btnLine.setActionCommand(CM_LINE);

		btnRectangle.addActionListener(this);
		btnRectangle.setActionCommand(CM_RECTANGLE);

		btnTriangle.addActionListener(this);
		btnTriangle.setActionCommand(CM_TRIANGLE);

		btnPoints.addActionListener(this);
		btnPoints.setActionCommand(CM_POINTS);

		btnQuad.addActionListener(this);
		btnQuad.setActionCommand(CM_QUAD);

		btnCustomShape.addActionListener(this);
		btnCustomShape.setActionCommand(CM_CUSTOM_SHAPE);

		btnBox.addActionListener(this);
		btnBox.setActionCommand(CM_BOX);

		btnArc.addActionListener(this);
		btnArc.setActionCommand(CM_ARC);

		btnCircle.addActionListener(this);
		btnCircle.setActionCommand(CM_CIRCLE);
		// Button commands - end

		// table.setPreferredScrollableViewportSize(new Dimension(500, 70));
		// table.setFillsViewportHeight(true);

		// Create the scroll pane and add the table to it.
		updateTable(false);

	}

	public void updateTable(final boolean dataConnected) {

		
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				panelDatabase.removeAll();
				if(!dataConnected)
					return;
				ArrayList<Shape> shapes = controller.getShapeFromDatabase();
				if (shapes == null || shapes.size() == 0)
					return; 
				JTable table = new JTable(new DefaultTableModel(new Object[] {
						"Id", "Shape type", "Description", "Element","Ordinate" }, 0));

				Iterator<Shape> i = shapes.iterator(); 
				while (i.hasNext()) {
					Shape shape = (Shape)i.next();
					DefaultTableModel model = (DefaultTableModel) table
							.getModel();
					model.addRow(new Object[] { String.valueOf(shape.getId()), shape.getShapeName(),
							shape.getDescription(),shape.getElementInfor(),shape.getOrdinateInfor() });
				}

				JScrollPane scrollPane = new JScrollPane(table);
				scrollPane
						.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
				panelDatabase.add(scrollPane);
			}
		});
	}

	public void updateDatabaseGUI(final boolean connected) {

		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				if (connected) {
					// connect
					lbdatabaseStatus.setText(Language.STATUS_CONNECTED);
				} else {
					lbdatabaseStatus.setText(Language.STATUS_DICONNECTED);
				}
			}
		});
	}

	protected void addNewShape(ShapeName shapeName) {
		if (currentShape != null) {
			currentShape.setName(shapeName);
			panel.removeAll();
			panel.add((PApplet) currentShape);
			((processing.core.PApplet) currentShape).init();
		}
	}

	@Override
	public void actionPerformed(ActionEvent event) {
		// TODO Auto-generated method stub

		switch (event.getActionCommand()) {
		case CM_SAVE: {
			saveDatabase();
		}
			break;
		case CM_LINE: {
			currentShape = ShapeFactory.getShape(ShapeName.LINE);
			addNewShape(ShapeName.LINE);
		}
			break;
		case CM_TRIANGLE: {
			currentShape = ShapeFactory.getShape(ShapeName.TRIANCLE);
			addNewShape(ShapeName.TRIANCLE);
		}
			break;
		case CM_RECTANGLE: {
			currentShape = ShapeFactory.getShape(ShapeName.RECTANGLE);
			addNewShape(ShapeName.RECTANGLE);
		}
			break;
		case CM_ELLIPSE: {
			currentShape = ShapeFactory.getShape(ShapeName.ELLIPSE);
			addNewShape(ShapeName.ELLIPSE);
		}
			break;
		case CM_POINTS: {
			currentShape = ShapeFactory.getShape(ShapeName.POINTS);
			addNewShape(ShapeName.POINTS);
		}
			break;
		case CM_BOX: {
			currentShape = ShapeFactory.getShape(ShapeName.BOX);
			addNewShape(ShapeName.BOX);
		}
			break;
		case CM_QUAD: {
			currentShape = ShapeFactory.getShape(ShapeName.QUAD);
			addNewShape(ShapeName.QUAD);
		}
			break;
		case CM_CUSTOM_SHAPE: {
			currentShape = ShapeFactory.getShape(ShapeName.CUSTOM_SHAPE);
			addNewShape(ShapeName.CUSTOM_SHAPE);
		}
			break;
		case CM_CIRCLE: {
			currentShape = ShapeFactory.getShape(ShapeName.CIRCLE);
			addNewShape(ShapeName.CIRCLE);
		}
			break;
		case CM_ARC: {
			currentShape = ShapeFactory.getShape(ShapeName.ARC);
			addNewShape(ShapeName.ARC);
		}
			break;
		default:
			break;
		}
		if (!event.getActionCommand().equals("CM_SAVE") && currentShape != null) {

			SwingUtilities.invokeLater(new Runnable() {
				public void run() {
					lbStatus.setText("");
				}
			});
			currentShape.setLabelNotify(lbStatus);
		}
	}

	protected void saveDatabase() {
		if (currentShape == null) {
			// Message box to user
			// Implement a messagebox class
			MessageBoxDialog.Show("Please draw a shape.", Language.APP_NAME,
					MessageBox.OK, MessageBoxIcon.WARNNING);
			return;
		}
		if (!controller.databaseIsConnected()) {
			MessageBoxDialog
					.Show("Can't save to database. Please connect to an Oracle database.",
							Language.APP_NAME, MessageBox.OK,
							MessageBoxIcon.WARNNING);
			return;
		}
		if (!controller.existingShapesTable()) {
			// create table here
			TABLE_STATUS status = controller.createShapeTable();
			if (status == TABLE_STATUS.CANT_CREATE) {
				MessageBoxDialog.Show(
						"Can't create a table in Oracle database.",
						Language.APP_NAME, MessageBox.OK,
						MessageBoxIcon.WARNNING);
				return;
			}
		}
		// base on current shape get file name corresponding
		// load json file to json array or json object
		// save to database

		Thread saveDataThread = new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				controller.saveShapeToDatabase(currentShape);
			}
		});
		saveDataThread.start();
	}

	public void saveSaveInfor(boolean saveSuccess) {
		if (saveSuccess) {
			SwingUtilities.invokeLater(new Runnable() {
				public void run() {
					MessageBoxDialog.Show(
							"Save shape to database successfully.",
							Language.APP_NAME, MessageBox.OK,
							MessageBoxIcon.INFORMATION);
				}
			});
			 
		} else {
			SwingUtilities.invokeLater(new Runnable() {
				public void run() {
					MessageBoxDialog.Show("Can't save this shape.",
							Language.APP_NAME, MessageBox.OK,
							MessageBoxIcon.ERROR);
				}
			});
		}
	}
}
